﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
/**
 * @author 梁峰源
 * @date 2021年7月26日15:46:00
 * 
 * 这个类主要用来处理FirstPageView里面指针圆盘的一些业务逻辑,包括画里面的刻度、更新刻度等等
 */
namespace fx.Controls
{
    /// <summary>
    /// Instrument.xaml 的交互逻辑
    /// </summary>
    public partial class Instrument : UserControl
    {
        //依赖属性,依赖对象


        public Brush PlateBackground
        {
            get { return (Brush)GetValue(PlateBackgroundProperty); }
            set { SetValue(PlateBackgroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PlateBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PlateBackgroundProperty =
            DependencyProperty.Register("PlateBackground", typeof(Brush), typeof(Instrument), new PropertyMetadata(default(Brush)));
      
        public int ScaleTextSize
        {
            get { return (int)GetValue(ScaleTextSizeProperty); }
            set { SetValue(ScaleTextSizeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ScleTextSize.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ScaleTextSizeProperty =
            DependencyProperty.Register("ScaleTextSize", typeof(int), typeof(Instrument), new PropertyMetadata(default(int)
               , new PropertyChangedCallback(OnpropertyChanged)));



        public Brush ScalePointBrush
        {
            get { return (Brush)GetValue(ScalePointBrushProperty); }
            set { SetValue(ScalePointBrushProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ScalePointBrush.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ScalePointBrushProperty =
            DependencyProperty.Register("ScalePointBrush", typeof(Brush), typeof(Instrument), new PropertyMetadata(default(Brush)
                , new PropertyChangedCallback(OnpropertyChanged)));


        public int Value
        {
            get { return (int)this.GetValue(ValueProperty); }
            set { this.SetValue(ValueProperty, value); }
        }
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(int), typeof(Instrument),    
                new PropertyMetadata(default(int),new PropertyChangedCallback(OnpropertyChanged)));


        //代码片段
        public int Mininum
        {
            get { return (int)GetValue(MininumProperty); }
            set { SetValue(MininumProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MininumProperty =
            DependencyProperty.Register("Mininum", typeof(int), typeof(Instrument), new PropertyMetadata(default(int)
                , new PropertyChangedCallback(OnpropertyChanged)));


        public int Maximum
        {
            get { return (int)GetValue(MaximumProperty); }
            set { SetValue(MaximumProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Maximum.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MaximumProperty =
            DependencyProperty.Register("Maximum", typeof(int), typeof(Instrument), new PropertyMetadata(default(int), 
                new PropertyChangedCallback(OnpropertyChanged)));



        public int Interval
        {
            get { return (int)GetValue(IntervalProperty); }
            set { SetValue(IntervalProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Interval.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IntervalProperty =
            DependencyProperty.Register("Interval", typeof(int), typeof(Instrument), new PropertyMetadata(default(int),
                 new PropertyChangedCallback(OnpropertyChanged)));



        public static void OnpropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
        {
            (d as Instrument).Refresh();
        }

        public Instrument()
        {
            InitializeComponent();
            this.SizeChanged += Instrument_SizeChanged;
        }

        private void Instrument_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            double minSize = Math.Min(this.RenderSize.Width, this.RenderSize.Height);
            this.backEllipse.Width = minSize;
            this.backEllipse.Height = minSize;
        }
        public void Refresh()
        {
            double radius = this.backEllipse.Width / 2;
            if (double.IsNaN(radius)) return;
            this.mainCanvas.Children.Clear();//只有最后一个才能画刻度
            //double min = 0, max = 100;
            //double Interval = 10;//每个区间里面分十份
            double step = 270.0 / (this.Maximum - this.Mininum);//均匀分份
            for(int i = 0; i < this.Maximum - this.Mininum; i++)
            {
                Line lineScale = new Line();
                
                lineScale.X1 = radius-(radius-15)*Math.Cos((i*step-45)*Math.PI/180);//计算出角度，并将角度转换成弧度
                lineScale.Y1 = radius-(radius-15) * Math.Sin((i * step -45) * Math.PI / 180);
                lineScale.X2 = radius-(radius-8) * Math.Cos((i * step -45) * Math.PI / 180);
                lineScale.Y2 = radius-(radius-8) * Math.Sin((i * step-45) * Math.PI / 180);
                lineScale.Stroke = this.ScalePointBrush;//设置线的颜色
                lineScale.StrokeThickness = 1;//设置线的厚度   
                this.mainCanvas.Children.Add(lineScale);
            }
            step =270.0 / Interval;
            int scaleText = (int)this.Mininum;
            for (int i = 0; i <= Interval; i++)
            {
                Line lineScale = new Line();
                //画短刻度
                lineScale.X1 = radius - (radius - 20) * Math.Cos((i * step - 45) * Math.PI / 180);//计算出角度，并将角度转换成弧度
                lineScale.Y1 = radius - (radius - 20) * Math.Sin((i * step - 45) * Math.PI / 180);
                lineScale.X2 = radius - (radius - 8) * Math.Cos((i * step - 45) * Math.PI / 180);
                lineScale.Y2 = radius - (radius - 8) * Math.Sin((i * step - 45) * Math.PI / 180);
                lineScale.Stroke = this.ScalePointBrush;//设置线的颜色
                lineScale.StrokeThickness = 1;//设置线的厚度  
                this.mainCanvas.Children.Add(lineScale);
                //画长刻度
                TextBlock textScale = new TextBlock();
                textScale.Width = 34;
                textScale.TextAlignment = TextAlignment.Center;
                textScale.FontSize = ScaleTextSize;
                textScale.Text = (scaleText + (this.Maximum- this.Mininum) / Interval * i).ToString();
                textScale.Foreground = this.ScalePointBrush;//设置字体的颜色
                Canvas.SetLeft(textScale, radius - (radius - 36) * Math.Cos((i * step - 45) * Math.PI / 180)-17);
                Canvas.SetTop(textScale, radius - (radius - 36) * Math.Sin((i * step - 45) * Math.PI / 180)-10);
                this.mainCanvas.Children.Add(textScale);
            }
            //画长刻度外面的数字
            string sData = "M{0} {1} A{0} {0} 0 1 1 {1} {2}";
            sData = string.Format(sData, radius / 2,radius,radius*1.5);
            var converter = TypeDescriptor.GetConverter(typeof(Geometry));
            this.circle.Data =(Geometry)converter.ConvertFrom(sData);
            //画指针
            step = 270.0 / (this.Maximum - this.Mininum);
            //this.rtPointer.Angle = this.Value * step - 45;
            //double value = double.IsNaN(this.Value) ? 0.0 : this.Value;
            //设置转动动画
            DoubleAnimation da = new DoubleAnimation((int)((this.Value - this.Mininum) * step) - 45,new Duration(TimeSpan.FromMilliseconds(200)));
            //将动画添加到其属性上面
            this.rtPointer.BeginAnimation(RotateTransform.AngleProperty, da);
            sData = "M{0} {1},{1} {2},{1} {3}";
            sData = string.Format(sData, radius*0.4, radius, radius-5, radius + 5);
            this.Pointer.Data = (Geometry)converter.ConvertFrom(sData);
        }
    }
}
